package com.gpscookie.redpanic;

import java.util.ArrayList;
import java.util.Random;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.Log;

public enum World {
	   INSTANCE;	// Singleton
	   
	   public int speed = 3;
	   public float playerSpeed = 3.7f;
	   public float width = 300;
	   public float height = 300;
	   public PlayerDot player = null;
	   public boolean paused = false;
	   public boolean over = true;
	   
	   private boolean debug = false;
	   private Paint bigTextPaint = null;
	   private Paint smallTextPaint = null;
	   private long timer = 0;
	   private int level = 0;
	   private int roundInLevel = 300;
	   private Random r;
	   private long score = 0;
	   private Context context;
	   private String strLevel;
	   private String strScore;
	   private String strRedDots;
	   private String strPaused;
	   private String strGameOver;
	   
	   
	   private ArrayList<RedDot> entitylist;
	   private ArrayList<BombDot> weaponlist;
	   private final int WEAPONS = 7;
	   
	   /**
	    * Initialize the world with a difficult level
	    */
	   public void init(Context c, int l) {
		   context = c;
		   r = new Random();
		   level = l;
		   timer = 0;
		   smallTextPaint = new Paint();
		   smallTextPaint.setColor(Color.BLACK);
		   smallTextPaint.setAntiAlias(true);
		   smallTextPaint.setTextSize(12);
		   smallTextPaint.setTypeface(Typeface.SERIF);    

		   bigTextPaint = new Paint();
		   bigTextPaint.setColor(Color.BLACK);
		   bigTextPaint.setAntiAlias(true);
		   bigTextPaint.setTextSize(18);
		   bigTextPaint.setTypeface(Typeface.SERIF);    
		   
		   // Place the player in the middle of the world
		   player = new PlayerDot(100, 100);
		   entitylist = new ArrayList<RedDot>();
		   weaponlist = new ArrayList<BombDot>();
		   createDots((int) (timer/roundInLevel+1)*10);		   
		   
		   strLevel = context.getResources().getString(R.string.level);
		   strScore = context.getResources().getString(R.string.score);
		   strRedDots = context.getResources().getString(R.string.reddots);
		   strPaused = context.getResources().getString(R.string.paused);
		   strGameOver = context.getResources().getString(R.string.gameover);
		   
	   }
	   
	   /**
	    * Render the world on a given canvas
	    */
	   public void render(Canvas canvas) {
		   canvas.drawColor(Color.WHITE);
		   player.draw(canvas);
		   // render all dots
		   for (int i=0; i<weaponlist.size(); i++) {
			   BombDot bomb = weaponlist.get(i);
			   if (bomb.isLive()) {
				   if (bomb.isOverlapped(player)) {
					   bomb.explode();
				   }
				   bomb.draw(canvas);
			   } else {
				   weaponlist.remove(i);
			   }
		   }			   
		   for (int i=0; i<entitylist.size(); i++) {
			   RedDot ent = entitylist.get(i);
			   if (ent.isLive()) {
				   for (BombDot bomb: weaponlist) {
					   if (bomb.isExploding() && bomb.isOverlapped(ent)) {
						   ent.explode();
					   }
				   }				   
				   if (ent.isLive()) {
					   ent.draw(canvas);
					   if (ent.isOverlapped(player)) {
						   Log.i("......","touch player");
						   player.explode();
					   }
				   } else {
					   entitylist.remove(i);
				   }
			   } else {
				   entitylist.remove(i);
			   }
		   }		   
		   if (debug) {
			   //canvas.drawText(String.format("Player:%f,%f", player.getX(), player.getY()), 
			   //		   10, height-20, smallTextPaint);
			   canvas.drawText(String.format("%s:%d   %s:%d   %s:%d", strLevel, level, "Timer", timer, strRedDots, entitylist.size()), 
					   10, height-20, smallTextPaint);
		   } else {
			   canvas.drawText(String.format("%s:%d   %s:%d   %s:%d", strLevel, level, strScore, score, strRedDots, entitylist.size()), 
					   10, height-20, smallTextPaint);			   
		   }
		   if (paused) {
			   canvas.drawText(strPaused, width/3, height/2, bigTextPaint);
		   }
		   if (over) {
			   canvas.drawText(strGameOver, width/3, height/2, bigTextPaint);
		   }
	   }
	   
	   private void createDots(int num) {
		   for (int i=0; i<num; i++) {
			   entitylist.add(getRandomRedDot());
		   }
	   }
	   
	   private BombDot getRandomWeapon() {
		   return new BombDot(r.nextInt(Math.round(width)), r.nextInt(Math.round(height)));
	   }
	   
	   private RedDot getRandomRedDot() {
		   RedDot rtn = null;
		   long random = r.nextInt()+Math.round(player.getX())+System.currentTimeMillis();
		   if (level==0) {
			   int index = (int) (random % 2);
			   switch (index) {
				   case 0:
					   // vertical
					   rtn = new LinearRedDot(r.nextInt(Math.round(width)), 0, 
							   r.nextInt(Math.round(width)), height, r.nextInt(speed-1)+1);
					   break;
				   case 1:
					   // horizontal
					   rtn = new LinearRedDot(0, r.nextInt(Math.round(height)), width, 
							   r.nextInt(Math.round(height)), r.nextInt(speed-1)+1);					   
					   break;
			   }
		   } else {
			   int index = (int) (random % 30);
			   Log.i("...index...", " "+index);
			   if (index>=0 && index<=10) {
				   // vertical
				   rtn = new LinearRedDot(r.nextInt(Math.round(width)), 0, 
						   r.nextInt(Math.round(width)), height, r.nextInt(speed-1)+1);
			   } else if (index>10 && index<=25) {
				   // horizontal
				   rtn = new LinearRedDot(0, r.nextInt(Math.round(height)), width, 
						   r.nextInt(Math.round(height)), r.nextInt(speed-1)+1);					   
			   } else {
				   // targeted missle
				   rtn = new MissleRedDot(0, r.nextInt(Math.round(height)), player.getLastx(),
						   player.getLasty(), r.nextInt(speed-1)+1);
			   }
		   }
		   return rtn;
	   }
	   
	   /**
	    * Forward the world one "day"
	    */
	   public void forward() {
		   if (paused || over) {
			   return;
		   }
		   // Increase the global timer
		   timer++;
		   score = timer/10;
		   long th = timer%roundInLevel;
		   if (entitylist.size()==0 || (th==0)) {
			   if (level<=3) {
				   createDots(10);
			   } else if (level>3 && level<=6) {
				   createDots(20);
			   } else if (level>6 && level<=10) {
				   createDots(30);
			   } else {
				   createDots(40);
			   }
			   level++;
		   }
		   for (Entity ent: entitylist) {
			   ent.step();
		   }		   
		   if (weaponlist.size()<WEAPONS) {
			   for (int i=weaponlist.size(); i<WEAPONS; i++) {
				   weaponlist.add(getRandomWeapon());
			   }
		   }		   
	   }

	   public void gameover() {
		   over = true;		   
	   }
}
